/*
 *  iacload.cpp
 *  EPPI-0.0
 *
 *  Created by Juan Carlos Garcia Orden on 15/11/07.
 *
 *  Modified by Pablo Antolin Sanchez on 10/12/2007.
 *  to communicate with GmcSocket.
*/

#include "iacload.h"

IACLoad::IACLoad()
:	Component(),
	socketName(),
	inp(),
	pTime(-1.0)
{}

// ***

IACLoad::~IACLoad()
{ 
	my_socket.unlink_path(); 
}

// ***

IACLoad::IACLoad(ifstream & in, string bodyName, int di,  const map<string,vector<string>,less<string> >* pset) 
:	Component(),
	socketName(),
	inp(),
	pTime(-1.0)
{
	dim = di;
	
	string keyword;
	string auxs;	/** Auxiliary string */
//	double auxd=0.0;	/** Auxiliary double */
	int i;
	map<string,vector<string>,less<string> > pointSets = *pset;
	
	/** Extract the system name where the body is */
	string sysName = getStringHead(bodyName);	
	while (in >> keyword && keyword.compare("ENDLOAD") )
	{
		if(!keyword.compare("POINT"))
		{
			while (in >> auxs && auxs.compare("SOCKETNAME") )
			{
				/** If it does not have slash, add it with the system name */
				if(checkForSlash(auxs)==false) addSystemName(auxs,sysName);
				pointNames.push_back(auxs);	
			}		
		}
		else if(!keyword.compare("POINTSET"))
		{
			in >> auxs;	// Name of pointSet
			
			for(i=0; i<pointSets[auxs].size(); ++i)	
			{
				//				cout << "anadiendo punto " << pointSets[auxs][i] << " de pointset " << auxs << "\n";
				pointNames.push_back(pointSets[auxs][i]);	
			}
			in >> auxs;
		}		
		if(!auxs.compare("SOCKETNAME"))
		{
			in >> socketName;
		//	inp.open(socketName);
			my_socket.set_recv_path(socketName);}
			my_socket.set_nonblock();
	}
	numDofs = dim*pointNames.size();
	Ft.resize(numDofs);
//	cout << "numDofs = " << numDofs << "\n";

}

// ***

void IACLoad::calcFi(const vector<double>& qddot)
{}

// ***

void IACLoad::calcFq(const int& nt)
{}

// ***

void IACLoad::calcFt(const double& t, const double& grav, const int& gravDir)
{
	int i=0;
	int j=0;
	double value;	

	if(Ft.size()==0) Ft.resize(numDofs);
	
	if(t!=pTime)
	{
		//if( inp >> value && inp.eof()==false)
		if( my_socket.receive()==1  )
		{
			value=*( (double *) my_socket.buffer );
			for(i=0; i<pointNames.size(); i++)
			{
				for(j=0; j<numDofs; j++) Ft[j + numDofs*i] = value;
			}
		}
	}
	pTime = t;
}

// ***

void IACLoad::calcKi(double & partial_qddot)
{}

// ***

void IACLoad::calcKq(int nt)
{}

// ***

void IACLoad::calcKdq(double & partial_qdot)
{}

// ***

void IACLoad::calcM(const vector<double>& q, const double& t)
{}

// ***

void IACLoad::calcMLumped(const vector<double>& q, const double& t)
{}

// ***

void IACLoad::setDofs(void)
{
	// It must not add any dof, but must set variable numDofs
	
 	map<string,Point*,less<string> >::iterator k;
	
	numDofsOnePoint = mPoints.begin()->second->countDofs();	// It is assumed that the two points have the same number of dofs
	numDofs = 0;
	for(k=mPoints.begin();k!=mPoints.end(); k++)	
	{
		numDofs += k->second->countDofs();
	}	
}

// ***

void IACLoad::initializeGlobalDofs(vector<double> &q_in, vector<double> &dq_in, const double& t )
{
	int i=0;
	
	if(q.size()==0)		/** If q has not been initialized yet, put dofs to 0 */
	{
		q.resize(numDofs);
		dq.resize(numDofs);
		
	}
	else if(dq.size()==0)
	{
		for(i=0; i<q.size(); i++)	dq_in[ localGlob[i] ] = 0.0 ;	/** From rest. Other initial condition  TO BE DONE. */
	}		
}

// ***

void IACLoad::setMatAtComp(Material* ma)
{}

// ***

void IACLoad::initializeCompRes(const bool& st, const double& grav, const int& gravDir, const bool augLagFlag)
{
	Ft.resize(numDofs);
}

// ***

//void IACLoad::initializeCompTang(const bool& st,  const bool& pf)
void IACLoad::initializeCompTang(const bool& st)
{}

// ***

void IACLoad::calcEner(double& Ekin, double& Epot, double& Econ, double& Eext, double& Eamb, double& Dint,double& grav, int& gravDir, vector<double>& q_in, vector<double>& dq_in)
{}

// ***

void IACLoad::calcEntropy(double& Entropy, double& EntropyAmb)
{}

// ***

void IACLoad::calcAM(vector<double>& am, vector<double>& q_in, vector<double>& dq_in)
{}	

// ***

void IACLoad::updateComp(void)
{}

// ***

void IACLoad::setIniDofs(vector<double>&)
{}

// ***

void IACLoad::calcPhi(const vector<double>&)
{}

// ***

void IACLoad::calcDPhi(const vector<double>&)
{}

// ***

void IACLoad::calcMSmooth(const vector<double>& q_in, const double& t)
{}

// ***

void IACLoad::calcFSmooth(const vector<double>& q_in, const vector<double>& dq_in, const double& t)
{}

int IACLoad::checkState()
{
return 0;
}
